<template>
  <div class="q-pa-md q-gutter-sm">
    <div class="row">
      <div class="col-2">
        <q-btn
          flat
          round
          color="primary"
          icon="add"
          @click="onUpdate('collection', null)"
        />
      </div>
      <div class="col-10">
        <q-input ref="filterRef" filled v-model="filter" label="Search">
          <template v-slot:append>
            <q-icon
              v-if="filter !== ''"
              name="clear"
              class="cursor-pointer"
              @click="resetFilter"
            />
          </template>
        </q-input>
      </div>
    </div>

    <q-tree
      no-nodes-label="添加目录"
      :nodes="collectionNode"
      dense
      node-key="id"
      :filter="filter"
      v-model:selected="selected"
    >
      <template v-slot:default-header="prop">
        <div class="row items-center">
          <q-icon
            :name="prop.node.icon || 'share'"
            color="orange"
            size="28px"
            class="q-mr-sm"
          />
          <div>
            <span @click="onClick(prop.node)">{{ prop.node.name }}</span>
            <q-btn
              style="margin-left: 6px"
              v-if="prop.node.icon == 'http'"
              size="xs"
              color="primary"
              flat
              icon="list"
            >
              <q-menu auto-close>
                <q-list style="min-width: 100px">
                  <q-item clickable @click="onCopy(prop.node)">
                    <q-item-section>复制</q-item-section>
                  </q-item>
                  <q-item clickable @click="onDelete(prop.node)">
                    <q-item-section>删除</q-item-section>
                  </q-item>
                  <q-separator />
                </q-list>
              </q-menu>
            </q-btn>
          </div>
          <q-btn
            v-if="prop.node.icon == 'folder'"
            round
            flat
            icon="more_horiz"
            size="xs"
          >
            <q-menu auto-close :offset="[-5, 0]">
              <q-list style="min-width: 100px">
                <q-item clickable @click="onUpdate('api', prop.node)">
                  <q-item-section> 添加API </q-item-section>
                </q-item>
                <q-item clickable @click="onUpdate('collection', prop.node)">
                  <q-item-section>添加目录</q-item-section>
                </q-item>
                <q-item clickable @click="onDelete(prop.node)">
                  <q-item-section>删除目录</q-item-section>
                </q-item>
              </q-list>
            </q-menu>
          </q-btn>
        </div>
      </template>
    </q-tree>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import { useQuasar } from "quasar";
import { invoke } from "@tauri-apps/api/tauri";
import { emitter } from "../boot/global_variable";
import { uuidv4 } from "../boot/tool";
const $q = useQuasar();

const selected = ref(null);
const workplaceID = ref("");

class Node {
  constructor() {
    this.id = "";
    this.name = "";
    this.icon = "";
    this.children = [];
  }
}

/* 过滤-START ***********/
const filter = ref("");
const constmyFilterMethod = (node, filter) => {
  const filt = filter.toLowerCase();
  return (
    node.label &&
    node.label.toLowerCase().indexOf(filt) > -1 &&
    node.label.toLowerCase().indexOf("(*)") > -1
  );
};
const resetFilter = () => {
  filter.value = "";
  filterRef.value.focus();
};

/* 过滤-END ***********/

// 节点
const collectionNode = ref([]);
// 测试
const test = async () => {
  const before = Date.now();
  console.log(before); // 1505722233092

  for (let i = 0; i < 100; i++) {
    let uuid = uuidv4();
    // let uuid = await invoke("uuid", {});
    console.log(uuid);
  }
  console.log(Date.now() - before, "ms"); // ms
};

// 添加api或collection
const onUpdate = async (type, node) => {
  console.log("[collections changed]=>", node);
  let title = "添加API";
  if (type == "collection") {
    title = "添加目录";
  }

  $q.dialog({
    title: title,
    prompt: {
      model: "",
      isValid: (val) => val.length > 0, // << here is the magic
      type: "text", // optional
    },
    cancel: true,
    persistent: true,
  }).onOk(async (name) => {
    // icon: folder,http
    const newNode = new Node();
    newNode.id = uuidv4();
    newNode.name = name;
    newNode.icon = "http";
    newNode.children = [];

    if (node == null) {
      newNode.icon = "folder";
      collectionNode.value.push(newNode);
    } else {
      if (type == "collection") {
        newNode.icon = "folder";
      } else {
        newNode.icon = "http";
      }

      node.children.push(newNode);

      // 存储
      try {
        const response = await invoke("collection_store", {
          wid: workplaceID.value,
          collections: collectionNode.value,
        });
        onClick(newNode);
      } catch (error) {
        console.log("[layout_cmd]=>", error);
      }
    }
  });
};

//点击node事件
const onClick = (node) => {
  if (node.icon == "http") {
    emitter.emit("node_changed", node);
    console.log("[node_changed:emit]=>", node);
  }
};

const copy = async (node) => {
  const newNode = new Node();
  newNode.id = uuidv4();
  newNode.icon = node.icon;
  newNode.name = node.name + " copy";
  newNode.children = node.children;
  // DFS算法
  for (let root of collectionNode.value) {
    var stack = [];
    stack.push(root);
    while (stack.length != 0) {
      var item = stack.pop();
      var children = item.children;
      for (var i = children.length - 1; i >= 0; i--) {
        if (children[i].id == node.id) {
          children.splice(i + 1, 0, newNode);
          await cloneFromDB(node.id, newNode.id);
          return;
        }
        stack.push(children[i]);
      }
    }
  }
};

const del = async (node) => {
  // DFS算法
  for (let root of collectionNode.value) {
    var stack = [];
    stack.push(root);
    while (stack.length != 0) {
      var item = stack.pop();
      var children = item.children;
      for (var i = children.length - 1; i >= 0; i--) {
        if (children[i].id == node.id) {
          children.splice(i, 1);
          await delFromDB(node.id);
          return;
        }
        stack.push(children[i]);
      }
    }
  }
};

const store = async () => {
  try {
    const response = await invoke("collection_store", {
      wid: workplaceID.value,
      collections: collectionNode.value,
    });
  } catch (error) {
    console.log("[layout_cmd]=>", error);
  }
};

const cloneFromDB = async (source, dist) => {
  try {
    const response = await invoke("api_clone", {
      source: source,
      dist: dist,
    });
    console.log("[api_clone]=>", response);
  } catch (error) {
    console.log("[api_clone]=>", error);
  }
};

const delFromDB = async (id) => {
  try {
    const response = await invoke("api_del", {
      id: id,
    });
    console.log("[api_del]=>", response);
  } catch (error) {
    console.log("[api_del]=>", error);
  }
};

// 复制
const onCopy = async (node) => {
  await copy(node);
  await store();
};

// 删除
const onDelete = async (node) => {
  await del(node);
  await store();

  // 通知
  emitter.emit("node_deleted", node.id);
  console.log("[node_deleted:emit]=>", node.id);
};

onMounted(() => {
  // 订阅workplace
  emitter.on("workplace_changed", async (wid) => {
    console.log("[workplace_changed:on]=>%s", wid);
    workplaceID.value = wid;
    await invoke("workpalce_cmd", { id: wid })
      .then((data) => {
        console.log("[workplace_changed:load]=>", data);
        collectionNode.value = data.collections;
      })
      .catch((error) => console.log("[workplace_changed:err]=>", error));
  });
});

onUnmounted(() => {
  emitter.off("workplace_changed");
  console.log("[emitter:off]=>workplace_changed");
});
</script>
